package forces;

import java.util.Collection;
import java.util.Scanner;
import simulation.Mass;


/**
 * This class represents a Wall repulsion force on masses.
 * 
 */
public class WallRepulsion extends Force {
    protected static final int TOP_WALL = 1;
    protected static final int RIGHT_WALL = 2;
    protected static final int BOTTOM_WALL = 3;
    protected static final int LEFT_WALL = 4;
    private static final double RIGHT_ANGLE = 90;
    private static final int SCREEN_HEIGHT = 600;
    private static final int SCREEN_WIDTH = 800;
    private static final double DEFAULT_MAGNITUDE = 100;
    private static final double DEFAULT_EXPONENT = 0;
    private int myId;
    private double myMagnitude;
    private double myExponent;

    /**
     * A default constructor that specifies a wall, magnitude, and exponent
     * for calculating the force.
     * 
     */
    public WallRepulsion (int id) {
        this(id, DEFAULT_MAGNITUDE, DEFAULT_EXPONENT);
    }

    /**
     * Creates a Wall Repulsion force with the specified wall, magnitude, and
     * exponent
     */
    public WallRepulsion (int id, double magnitude, double exponent) {
        super();
        myId = id;
        myMagnitude = magnitude;
        myExponent = exponent;
    }

    public WallRepulsion (Scanner line) {
        this(line.nextInt(), line.nextDouble(), line.nextDouble());
    }

    /**
     * Implements the abstract update method to calculate and apply
     * the wall repulsion force on each mass.
     */
    @Override
    public void update (Collection<Mass> masses) {
        for (Mass m : masses) {
            double distance = 0;
            if (myId == TOP_WALL) {
                distance = m.getY();
            }
            else if (myId == RIGHT_WALL) {
                distance = SCREEN_WIDTH - m.getX();
            }
            else if (myId == BOTTOM_WALL) {
                distance = SCREEN_HEIGHT - m.getY();
            }
            else if (myId == LEFT_WALL) {
                distance = m.getX();
            }

            setMagnitude(myMagnitude / Math.pow(distance, myExponent));
            setDirection(RIGHT_ANGLE * myId);
            m.applyForce(this);
        }
    }
}
